package com.rockcent.mall.lib.helper;

import com.rockcent.common.utils.BigDecimalUtils;
import com.rockcent.mall.lib.domain.MallOrder;
import com.rockcent.mall.lib.domain.MarketOrder;
import com.rockcent.mall.lib.domain.MerchantCoupon;
import com.rockcent.mall.lib.domain.MerchantCouponProducts;
import com.rockcent.mall.lib.domain.enumclass.CouponType;
import com.rockcent.mall.lib.domain.enumclass.CouponUseScope;
import com.rockcent.mall.lib.domain.enumclass.OrderStatus;
import com.rockcent.mall.lib.domain.enumclass.ProductType;
import com.rockcent.mall.lib.dto.BuyOrderDto;
import com.rockcent.mall.lib.dto.BuyProductDto;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by oyhk on 2016/11/25.
 * 平台流程帮助类
 */
public enum OrderHelper {
    SINGLEONE;

    /**
     * 生成平台支付流水号
     *
     * @return
     */
    public String genMallOrderPaymentFlowNumber() {
        return String.format("%s%d", DateFormatUtils.format(new Date(), "yyyyMMddHHmmddSSS"), new Random().nextInt(8999999) + 1000000);
    }

    /**
     * 生成平台支付号
     *
     * @return
     */
    public String genMallOrderPaymentNumber() {
        return String.format("%s%d", DateFormatUtils.format(new Date(), "yyyyMMddHHmmddSSS"), new Random().nextInt(8999999) + 1000000);
    }

    /**
     * 生成平台订单号
     * 格式：
     * 时间戳+平台号+订单类型
     *
     * @return
     */
    public String genMallOrderNumber(Long mallId, BuyOrderDto buyOrderDto) {

        Long type = 3L; // 默认礼包类型

        List<ProductType> productTypeList = Arrays.asList(ProductType.GOODS, ProductType.SERVICE);
        List<ProductType> buyProductTypeList = buyOrderDto.getBuyProductList().stream().map(BuyProductDto::getType).collect(Collectors.toList());

        if (buyOrderDto.getBuyGiftPacketId() != null) {
            type = 3L;// 默认礼包下单
        } else {
            if (buyProductTypeList.equals(productTypeList)) {
                type = 2L; // 混合下单
            } else if (!buyProductTypeList.contains(ProductType.GOODS)) {
                type = 1L; // 单服务下单
            } else if (!buyProductTypeList.contains(ProductType.SERVICE)) {
                type = 0L; // 单商品下单
            }
        }


        return String.format("%s%d%d", String.format("%03d", mallId), type, new Date().getTime());
    }

    /**
     * 生成商家订单号
     *
     * @return
     */
    public String genMerchantOrderNumber(String mallOrderNum, List<Long> count) {
        count.add(1L);
        return String.format("%s_%d", mallOrderNum, count.size());
    }

    /**
     * 生成分销订单号
     *
     * @return
     */
    public String genMarketOrderNumber() {
        return String.format("%s%d", DateFormatUtils.format(new Date(), "yyyyMMddHHmmddSSS"), new Random().nextInt(8999999) + 1000000);
    }


    /**
     * 计算 mall_order 订单折扣销售总价
     *
     * @param buyProductDtoList          购买产品列表
     * @param merchantCouponProductsList 卡券可用产品列表
     * @param merchantCoupon             卡券
     * @return
     */
    public BigDecimal calculatedMallOrderDiscountTotalAmount(List<BuyProductDto> buyProductDtoList, List<MerchantCouponProducts> merchantCouponProductsList, MerchantCoupon merchantCoupon) {


        BigDecimal totalAmount = this.calculatedMallOrderSellTotalAmount(buyProductDtoList);
        BigDecimal couponDiscountAmount = this.calculatedMallOrderCouponDiscountAmount(buyProductDtoList, merchantCouponProductsList, merchantCoupon);
        totalAmount = totalAmount.subtract(couponDiscountAmount);
        return totalAmount;
    }

    /**
     * 计算平台订单卡券优惠金额
     *
     * @param buyProductDtoList
     * @param merchantCouponProductsList
     * @param merchantCoupon
     * @return
     */
    public BigDecimal calculatedMallOrderCouponDiscountAmount(List<BuyProductDto> buyProductDtoList, List<MerchantCouponProducts> merchantCouponProductsList, MerchantCoupon merchantCoupon) {

        BigDecimal couponDiscountAmount = BigDecimal.ZERO; // 对应商家产品,使用优惠券后的价格
        if (merchantCoupon == null) {
            return couponDiscountAmount;
        }
        // 使用优惠券
        Map<Long, BuyProductDto> buyProductDtoMap = buyProductDtoList.stream().collect(Collectors.toMap(BuyProductDto::getBuyId, dto -> dto));
        if (merchantCoupon.getUseScope() == CouponUseScope.ALL_PRODUCT) {
            if (merchantCoupon.getType() == CouponType.VOUCHERS) { // 抵用券
                boolean use = false; // 是否商家可用产品
                for (BuyProductDto buyProductDto : buyProductDtoList) {
                    if (Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId()) && buyProductDto.getMarketId() == 0L) { // 卡券可用商家并且购买产品包含自营产品
                        use = true;
                    }
                }
                if (use) {
                    couponDiscountAmount = merchantCoupon.getFaceValue();
                }
            } else if (merchantCoupon.getType() == CouponType.DISCOUNT) { //折扣券
                for (BuyProductDto buyProductDto : buyProductDtoList) {
                    if (Objects.equals(merchantCoupon.getMerchantId(), buyProductDto.getMerchantId()) && buyProductDto.getMarketId() == 0L) {// 自营商品才能使用优惠卡券
                        // 计算此产品总销售价
                        BigDecimal productSellTotalPrice = buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount()));
                        // 计算此产品卡券优惠价
                        BigDecimal discountAmount = productSellTotalPrice.multiply(BigDecimalUtils.divide(merchantCoupon.getDiscount(), "10"));
                        couponDiscountAmount = couponDiscountAmount.add(productSellTotalPrice.subtract(discountAmount));
                    }
                }
            }
        }
        if (merchantCoupon.getUseScope() == CouponUseScope.PART_PRODUCT && merchantCouponProductsList.size() > 0) {
            if (merchantCoupon.getType() == CouponType.VOUCHERS) { // 抵用券
                boolean use = false; // 是否商家可用产品
                for (BuyProductDto buyProductDto : buyProductDtoList) {
                    if (Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId()) && buyProductDto.getMarketId() == 0L) { // 卡券可用商家并且购买产品包含自营产品
                        use = true;
                    }
                }
                if (use) {
                    couponDiscountAmount = merchantCoupon.getFaceValue();
                }
            } else if (merchantCoupon.getType() == CouponType.DISCOUNT) { //折扣券
                List<Long> merchantCouponProductIdList = merchantCouponProductsList.stream().map(MerchantCouponProducts::getProductId).collect(Collectors.toList());
                for (Long productId : merchantCouponProductIdList) {
                    BuyProductDto buyProductDto = buyProductDtoMap.get(productId);
                    if (buyProductDto != null && buyProductDto.getMarketId() == 0L) { // 自营商品才能使用优惠卡券
                        // 计算此产品总销售价
                        BigDecimal productSellTotalPrice = buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount()));
                        // 计算此产品卡券优惠价
                        BigDecimal discountAmount = productSellTotalPrice.multiply(BigDecimalUtils.divide(BigDecimal.valueOf(10).subtract(merchantCoupon.getDiscount()), "10"));
                        couponDiscountAmount = couponDiscountAmount.add(discountAmount);
                    }
                }
            }
        }
        return couponDiscountAmount;
    }

    /**
     * 计算 mall_order 订单销售价总价
     *
     * @param buyProductDtoList 购买产品列表
     * @return
     */
    public BigDecimal calculatedMallOrderSellTotalAmount(List<BuyProductDto> buyProductDtoList) {
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (BuyProductDto buyProduct : buyProductDtoList) {
            totalAmount = totalAmount.add(buyProduct.getSellPrice().multiply(new BigDecimal(buyProduct.getBuyCount())));
        }
        return totalAmount;
    }

    /**
     * 计算 mall_order 订单原价总价
     *
     * @param buyProductDtoList 购买产品列表
     * @return
     */
    public BigDecimal calculatedMallOrderBaseTotalAmount(List<BuyProductDto> buyProductDtoList) {
        BigDecimal totalAmount = BigDecimal.valueOf(0);
        for (BuyProductDto buyProduct : buyProductDtoList) {
            BigDecimal basePrice = buyProduct.getBasePrice() == null ? BigDecimal.valueOf(0) : buyProduct.getBasePrice();
            totalAmount = totalAmount.add(basePrice.multiply(new BigDecimal(buyProduct.getBuyCount())));
        }
        return totalAmount;
    }

    /**
     * 计算 merchant_order 订单销售价总价
     *
     * @param buyProductDtoList 购买产品列表
     * @return
     */
    public BigDecimal calculatedMerchantOrderSellTotalAmount(List<BuyProductDto> buyProductDtoList) {
        BigDecimal totalAmount = BigDecimal.valueOf(0);
        for (BuyProductDto buyProduct : buyProductDtoList) {
            BigDecimal sellPrice = buyProduct.getSellPrice();
            totalAmount = totalAmount.add(sellPrice.multiply(new BigDecimal(buyProduct.getBuyCount())));
        }
        return totalAmount;
    }

    /**
     * 计算购买产品可使用卡券的消费金额
     *
     * @param buyProductDtoList 购买产品列表
     * @param merchantCoupon    卡券
     * @return
     */
    public BigDecimal calculatedLimitAmount(List<BuyProductDto> buyProductDtoList, MerchantCoupon merchantCoupon) {
        BigDecimal limitAmount = BigDecimal.ZERO;
        for (BuyProductDto buyProduct : buyProductDtoList) {
            // 找出 对应购买产品的购买数量
            if (Objects.equals(buyProduct.getMerchantId(), merchantCoupon.getMerchantId())) {
                limitAmount = limitAmount.add(buyProduct.getSellPrice().multiply(new BigDecimal(buyProduct.getBuyCount()))); // 产品销售金额 * 购买数量 , 不断累减
            }
        }
        return limitAmount;
    }


    /**
     * 包装分销市场订单
     *
     * @param sourceProduct
     * @param supplierProduct
     * @param distributorMallOrder
     * @return
     */
    public MarketOrder packageMarketOrder(BuyProductDto sourceProduct, BuyProductDto supplierProduct, MallOrder distributorMallOrder) {
        MarketOrder marketOrder = new MarketOrder();
        marketOrder.setOrderNum(this.genMarketOrderNumber());
        marketOrder.setBuyCount(sourceProduct.getBuyCount());
        marketOrder.setDistributorMerchantName(sourceProduct.getMerchantName());
        marketOrder.setDistributorMallId(sourceProduct.getMallId());
        marketOrder.setDistributorMerchantId(sourceProduct.getMerchantId());
        marketOrder.setDistributorMallOrderNum(distributorMallOrder.getOrderNum());
        marketOrder.setSupplierMallId(supplierProduct.getMallId());
        marketOrder.setSupplierMerchantId(supplierProduct.getMerchantId());
        marketOrder.setSupplierMerchatName(supplierProduct.getMerchantName());
        marketOrder.setSupplierProductId(supplierProduct.getId());
        marketOrder.setStatus(OrderStatus.WAIT_PAYING);
        marketOrder.setTotalAmount(supplierProduct.getSellPrice().multiply(new BigDecimal(sourceProduct.getBuyCount())));
        return marketOrder;
    }

}
